﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kaleta.Xna.Distributed;
using Microsoft.Xna.Framework;
using Kaleta.Xna.Collision;
using Microsoft.Xna.Framework.Graphics;
using Kaleta.Network;
using Kaleta.Xna.Timing;

namespace Kaleta.Outcast
{
    public class Bullet : DistributedSolidBody
    {

        public Bullet()
        {
            this.Texture = Global.SpriteSheets.Bullet.Texture;
            this.Body = new Body()
            {
                Origin = new Vector2(this.Texture.Width / 2f, this.Texture.Height / 2f),
                Scale = new Vector2(0.15f)
            };


            #region Registration of distributed properties
            _livetime = DistributableProperty<Livetime>.Register("Livetime", this, Lidgren.Network.NetChannel.ReliableInOrder1);
            #endregion

        }

        public override void Update(GameTime gameTime)
        {
            this.Body.Position = new Vector2()
            {
                X = this.Body.Position.X + this.Velocity.X,
                Y = this.Body.Position.Y + this.Velocity.Y
            };

            this.storyboard.Update(gameTime);
        }

        public override void Draw(SpriteBatch batch)
        {
            batch.Draw(this.Texture, this.Position, null, Color.White, this.Body.Direction, this.Body.Origin, this.Body.Scale, SpriteEffects.None, 0);
        }

        public override void OnCollision(IBody obstacle, List<BodyShape> intersectingColliderShapes, List<BodyShape> intersectingObstacleShapes)
        {

        }

        #region Server-side events

        private void OnLivetimeUpdate(ref Livetime oldValue)
        {
            //only host can handle livetime of objects:
            if (DistributionSession.Server == null)
                return;

            if (this.Livetime == Livetime.Created)
            {
                ActionTimeline action = new ActionTimeline(500f, delegate() { this.Livetime = Livetime.Disposed; });
                this.storyboard.Add(action);
            }

            if (this.Livetime == Livetime.Disposed)
            {
                DistributionSession.Dispose(this);
            }
        }

        #endregion

        #region Public Properties

        #endregion

        #region Private Properties

        private Storyboard storyboard = new Storyboard();

        #endregion

        #region Distributed properties

        [Distribute]
        public Vector2 Velocity { get; set; }

        [Distribute]
        public Livetime Livetime
        {
            get
            {
                return _livetime.GetValue();
            }
            set
            {
                Livetime oldValue;

                if (_livetime.SetValue(value, out oldValue))
                    OnLivetimeUpdate(ref oldValue);
            }
        }
        private DistributableProperty<Livetime> _livetime;


        #endregion

    }

    #region Enums

    public enum Livetime : uint
    {
        Created = 1,
        Disposed = 2,
    }

    #endregion
}
